﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace ProductCollector {
    public class AmazonSearcher : ISiteSearcher {
        private const string MY_AWS_ACCESS_KEY_ID = "AKIAIRYB2PXBYBKVM56Q";
        private const string MY_AWS_SECRET_KEY = "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";
        private const string DESTINATION = "webservices.amazon.com";
        SignedRequestHelper helper = new SignedRequestHelper(MY_AWS_ACCESS_KEY_ID, MY_AWS_SECRET_KEY, DESTINATION);
        private const string NAMESPACE = "http://webservices.amazon.com/AWSECommerceService/2011-08-01";
        public IList<Product> Search(SearchCriteria criteria) {
            String requestString = "Service=AWSECommerceService"
                     + "&Version=2011-08-01"
                     + "&AssociateTag=your_own_tag"
                     + "&Operation=ItemSearch"
                     + "&SearchIndex=All"
                     + "&ResponseGroup=Medium"
                     + "&Keywords=" + criteria.SearchValue
                     ;
            var url = helper.Sign(requestString);
            var products = GetProducts(url);
            return products.Result;
        }

        public int CountProduct(SearchCriteria criteria) {
            throw new NotImplementedException();
        }
        private static async Task<List<Product>> GetProducts(string url) {
            Boolean validRequest = false;
            List<Product> products = new List<Product>();
            try {
                HttpClient client = new HttpClient();
                HttpResponseMessage response = await client.GetAsync(url);
                response.EnsureSuccessStatusCode();
                XElement content = await response.Content.ReadAsAsync<XElement>();
                XNamespace ns = NAMESPACE;
                var isValidResults = content.Descendants(ns + "IsValid").AsParallel();

                foreach (var item in isValidResults) {
                    if (item.Value == "True")
                        validRequest = true;
                    else
                        return products;
                }

                if (validRequest) {
                    XmlNameTable nameTable =new NameTable();
                    XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
                    namespaceManager.AddNamespace(ns.NamespaceName,NAMESPACE);
                    var titleResults = content.Descendants(ns + "Item").AsParallel();
                    foreach (var item in titleResults) {
                        var p = new Product();
                        var largeImage = item.Descendants(ns + "LargeImage").FirstOrDefault();
                        if (largeImage != null) {
                            var img = largeImage.Descendants(ns+"URL").FirstOrDefault();
                            if (img != null) {
                                p.ThumbImg = img.Value;
                            }
                        }

                        var attribute = item.Descendants(ns + "ItemAttributes").FirstOrDefault();
                        if (attribute != null) {
                            var man = attribute
                                          .Descendants(ns + "Manufacturer").FirstOrDefault();
                            if (man != null) {
                                p.Manufacturer = man.Value;
                            }
                            var title = attribute.Descendants(ns+"Title").FirstOrDefault();
                            if (title != null) {
                                p.Description = title.Value;
                            }
                        }
                        
                        var id = item.Descendants(ns+ "ASIN").FirstOrDefault();
                        if (id != null) {
                            p.ProductName = id.Value;
                        }
                        var fPrice = item.Descendants(ns + "OfferSummary").FirstOrDefault();
                        if (fPrice != null) {
                            var price = fPrice
                                            .Descendants(ns + "FormattedPrice").FirstOrDefault();
                            if (price != null) {
                                p.FormattedPrice = price.Value;
                            }
                        }
                        var pLink = item.Descendants(ns+"DetailPageURL").FirstOrDefault();
                        if (pLink != null) {
                            p.OriginalUrl = pLink.Value;
                        }
                        products.Add(p);
                       
                    }
                }

            } catch (Exception e) {
                System.Console.WriteLine("Caught Exception: " + e.Message);
                System.Console.WriteLine("Stack Trace: " + e.StackTrace);
            }

            return products;
        }
    }
}
